package com.superzlc.vcontroller.ctrlwidget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 方向盘
 *
 * @author superzlc
 *
 */
public class SteeringWheelView extends View {

	private Paint paint;

	public SteeringWheelView(Context context) {
		super(context);
		paint = new Paint();
		paint.setARGB(0x7f, 0xdf, 0x30, 0x30);
		this.setMeasuredDimension(400, 400);
		// this.setOnClickListener(l);
		// this.setOnDragListener(l);
		// this.setOnTouchListener(l);

		thread.start();
	}

	private final float minAngle = -900;
	private final float maxAngle = 900;

	private float w, h;
	private float cx, cy;

	private float radiusCtrlA; // 方向盘控制最小半径
	private float radiusCtrlB; // 方向盘控制最大半径
	private float radiusCtrlAA; // 方向盘控制最小半径的平方
	private float radiusCtrlBB; // 方向盘控制最大半径的平方
	private float radiusDrawA; // 方向盘绘制最小半径
	private float radiusDrawB; // 方向盘绘制最大半径
	private float radiusDrawC; // 临时值，方向盘绘制半径差 = radiusDrawB - radiusCtrlA;
	private float radiusDrawD; // 临时值，方向盘绘制平均半径= radiusDrawA + (radiusDrawB - radiusCtrlA) / 2;
	private float radiusDrawE; // 最中间的圆形

	public void setWidthAndHeight(int w, int h) {
		Log.i("vjoy", "设置大小");
		this.w = w;
		this.h = h;
		this.cx = this.w / 2;
		this.cy = this.h / 2;
		float t = this.w > this.h ? this.h : this.w;
		radiusCtrlB = t * 0.5f;
		radiusCtrlA = t * 0.1f;
		radiusCtrlBB = radiusCtrlB * radiusCtrlB;
		radiusCtrlAA = radiusCtrlA * radiusCtrlA;
		radiusDrawB = t * 0.4f;
		radiusDrawA = t * 0.3f;
		radiusDrawC = radiusDrawB - radiusDrawA;
		radiusDrawD = radiusDrawA + 1 + radiusDrawC / 2;
		radiusDrawE = radiusDrawC;
	}

	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		Log.i("vjoy", "自动设置大小");
		this.setWidthAndHeight(w, h);
	}

	protected void onDraw(Canvas canvas) {
		canvas.drawColor(Color.GRAY);

		paint.setStyle(Paint.Style.STROKE);

		// 绘制方向盘圆环
		paint.setARGB(255, 0, 255, 0);
		paint.setStrokeWidth(radiusDrawC);
		canvas.drawCircle(cx, cy, radiusDrawD, paint);

		// 绘制方向盘外圆
		paint.setARGB(155, 0, 0, 255);
		paint.setStrokeWidth(2);
		canvas.drawCircle(cx, cy, radiusDrawB, paint);

		// 绘制方向盘内圆
		paint.setARGB(155, 255, 0, 0);
		paint.setStrokeWidth(2);
		canvas.drawCircle(cx, cy, radiusDrawA, paint);

		// 绘制方向盘中间
		paint.setARGB(255, 255, 0, 0);
		paint.setStrokeWidth(radiusDrawE);
		canvas.drawCircle(cx, cy, radiusDrawE / 2, paint);

		// 绘制方向盘中间杆

		paint.setStrokeWidth(radiusDrawE);
		double t1 = (realAngle + 190 + 90) % 360;
		t1 = t1 * Math.PI / 180;
		double a1 = cx + radiusDrawA * Math.cos(t1);
		double b1 = cy + radiusDrawA * Math.sin(t1);
		canvas.drawLine(cx, cy, (float)a1, (float)b1, paint);
		double t2 = (realAngle + 350 + 90) % 360;
		t2 = t2 * Math.PI / 180;
		double a2 = cx + radiusDrawA * Math.cos(t2);
		double b2 = cy + radiusDrawA * Math.sin(t2);
		canvas.drawLine(cx, cy, (float)a2, (float)b2, paint);
		double t3 = (realAngle + 90 + 90) % 360;
		t3 = t3 * Math.PI / 180;
		double a3 = cx + radiusDrawA * Math.cos(t3);
		double b3 = cy + radiusDrawA * Math.sin(t3);
		canvas.drawLine(cx, cy, (float)a3, (float)b3, paint);

		if (this.isAutoToZero) {
			paint.setColor(Color.BLUE);
		} else {
			paint.setColor(Color.GRAY);
		}
		paint.setStrokeWidth(radiusDrawE / 2);
		canvas.drawCircle(cx, cy, radiusDrawE / 4, paint);

		//
		paint.setARGB(255, 255, 0, 0);
		paint.setTextSize(40);
		paint.setStrokeWidth(1);
		canvas.drawText("当前绝对度数: " + realAngle, 50, 50, paint);
		canvas.drawText("当前相对度数: " + relativeAngle, 50, 100, paint);
		canvas.drawText("旧确定度数: " + oldAngle, 50, 150, paint);
		canvas.drawText("Message: " + message, 50, 200, paint);
		canvas.drawText("axis: " + this.getAsix(), 50, 250, paint);
	}

	@Override
	public boolean performClick() {
		return super.performClick();
	}

	private boolean isAutoToZero = true;
	private boolean isTurning = false; // 正在转动
	private float baseAngle; // 转动开始角度
	private float oldAngle; // 前一次转动的度数
	private float nowAngle; // 当前转动的度数
	private float multiTurnAngle = 0; // 多圈补偿

	private float relativeAngle = 0; // 相对转动度数
	private float oldRealAngle = 0;
	private float realAngle = 0; // 整体转动度数

	private String message = "Hi";

	private int point = 0;

	final float rate = 32767 / (maxAngle - minAngle);
	public int getAsix() {
		return (int)((realAngle + 900) * rate);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction() & MotionEvent.ACTION_MASK) {

		case MotionEvent.ACTION_MOVE:
			//point = event.getPointerCount() - 1;
			//Log.i("vjoy", "onTouchEvent.ACTION_MOVE - point " + point);
			if (isInCtrl(event.getX(point), event.getY(point)) == 1) {
				if (!isTurning) {
					synchronized (flag) {
						isTurning = true;
					}
					relativeAngle = 0;
					multiTurnAngle = 0;
					baseAngle = calcAngle(event.getX(point) - cx, event.getY(point) - cy);
					oldAngle = baseAngle;
					oldRealAngle = realAngle;
				} else {
					turn(event.getX(point) - cx, event.getY(point) - cy);
					this.invalidate();
				}
			} else {
				synchronized (flag) {
					isTurning = false;
					flag.notify();
				}
			}
			break;
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			synchronized (flag) {
				isTurning = false;
				this.invalidate();
				flag.notify();
			}
			break;
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
			//point = event.getPointerCount() - 1;
			//Log.i("vjoy", "onTouchEvent.ACTION_MOVE - point " + point);
			if (isInCtrl(event.getX(point), event.getY(point)) == 1) {
				synchronized (flag) {
					isTurning = true;
				}
				relativeAngle = 0;
				multiTurnAngle = 0;
				baseAngle = calcAngle(event.getX(point) - cx, event.getY(point) - cy);
				oldAngle = baseAngle;
				oldRealAngle = realAngle;
			} else {
				synchronized (flag) {
					isTurning = false;
					flag.notify();
				}
				if (isInCtrl(event.getX(point), event.getY(point)) == 0) {
					isAutoToZero = !isAutoToZero;
				}
			}
			this.invalidate();
			break;
		}
		return true;
	}

	private int isInCtrl(float x, float y) {
		float x1 = (x - cx);
		float y1 = (y - cy);
		x1 = x1 * x1 + y1 * y1;
		if (x1 > radiusCtrlBB) { // 方向盘控制区外
			return -1;
		}
		if (x1 < radiusCtrlAA) { // 方向盘控制区内
			return 0;
		}
		return 1; // 方向盘控制区
	}

	private void turn(float x, float y) {
		nowAngle = calcAngle(x, y);
		final int k = 20; // 边界检测范围
		if (oldAngle > 0 && oldAngle < k && nowAngle > 360 - k) { // 逆时针过界
			multiTurnAngle -= 360;
			Log.i("vjoy", "逆时针过界");
		} else if (oldAngle < 360 && oldAngle > 360 - k && nowAngle < k) { // 顺时针过界
			multiTurnAngle += 360;
			Log.i("vjoy", "正时针过界");
		}

		relativeAngle = nowAngle - baseAngle + multiTurnAngle;
		realAngle = oldRealAngle + relativeAngle;

		if (realAngle > maxAngle) {
			realAngle = maxAngle;
			relativeAngle = 0;
			multiTurnAngle = 0;
			baseAngle = calcAngle(x, y);
			oldAngle = baseAngle;
			oldRealAngle = realAngle;
		} else if (realAngle < minAngle) {
			realAngle = minAngle;
			relativeAngle = 0;
			multiTurnAngle = 0;
			baseAngle = calcAngle(x, y);
			oldAngle = baseAngle;
			oldRealAngle = realAngle;
		}

		//Log.i("vjoy", "当前相对度数: " + relativeAngle);
		//Log.i("vjoy", "当前实际度数: " + realAngle);
		oldAngle = nowAngle;
	}

	public Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				invalidate();
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};

	Thread thread = new Thread() {
		public void run() {
			autoToZero();
		}
	};

	Object flag = new Object();
	private void autoToZero() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		while(true) {
			try {
				synchronized (flag) {
					if (isTurning || realAngle == 0 || !isAutoToZero)
						flag.wait();
				}
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			if (!isTurning && isAutoToZero) {
				if (realAngle > -2 && realAngle < 2) {
					realAngle = 0;
				} else {
					if (realAngle > 0) {
						realAngle -= 2;
					} else {
						realAngle += 2;
					}
				}
				Message msg = new Message();
				msg.what = 1;
				mHandler.sendMessage(msg);
				message = "刷新realAngle：" + realAngle;
			}
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	// 计算角度，返回值[0, 360)度
	private static float calcAngle(float x, float y) {
		double radian;

		if (x != 0) {
			float tan = Math.abs(y / x);
			if (x > 0) {
				if (y >= 0) {
					radian = Math.atan(tan);
				} else {
					radian = 2 * Math.PI - Math.atan(tan);
				}
			} else {
				if (y >= 0) {
					radian = Math.PI - Math.atan(tan);
				} else {
					radian = Math.PI + Math.atan(tan);
				}
			}
		} else {
			if (y > 0) {
				radian = Math.PI / 2;
			} else {
				radian = -Math.PI / 2;
			}
		}
		return (float) ((radian * 180) / Math.PI);
	}

}
